package org.zoomdev.zoom.dao.impl;

import org.apache.commons.lang3.StringUtils;
import org.zoomdev.zoom.dao.DaoException;
import org.zoomdev.zoom.dao.EntityField;
import org.zoomdev.zoom.dao.Record;
import org.zoomdev.zoom.dao.meta.JoinMeta;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;

public final class RecordEntity extends AbstractEntity<Record> {


    private final Map<String, EntityField> pool = new ConcurrentHashMap<String, EntityField>();


    RecordEntity(TableSource table,
                 EntityField[] entityFields,
                 EntityField[] primaryKeys,
                 AutoGenerator autoGenerator,
                 HashMap<String, String> namesMap,
                 JoinMeta[] joins) {
        super(table, entityFields, primaryKeys, autoGenerator, namesMap, joins);
    }

    @Override
    public Class<Record> getType() {
        return Record.class;
    }

    @Override
    public Record newInstance() {
        return new Record();
    }


    public List<EntityField> select(
            List<EntityField> holder,
            Iterable<String> fields
    ) {
        for (String key : fields) {
            EntityField field = pool.get(key);
            if (field == null) {
                Matcher matcher;
                String fieldName;
                String alias = null;
                if ((matcher = RecordSqlUtils.AS_PATTERN.matcher(key)).matches()) {
                    fieldName = matcher.group(1);
                    alias = matcher.group(2);

                } else {
                    fieldName = key;
                }
                RecordEntityField entityField = (RecordEntityField) tryToFind(fieldName);
                if (entityField == null) {
                    throw new DaoException("找不到" + key + "对应的字段,所有可能的字段为" + StringUtils.join(getAvailableFields()));
                }

                if (alias != null) {
                    try {
                        RecordEntityField recordEntityField = (RecordEntityField) entityField.clone();
                        recordEntityField.field = alias;
                        pool.put(key, recordEntityField);
                        field = recordEntityField;
                    } catch (CloneNotSupportedException e) {
                        throw new DaoException(e);
                    }
                } else {
                    field = entityField;
                    pool.put(key, entityField);
                }
            }
            holder.add(field);
        }

        return holder;
    }


}
